////////////////////////////////////////////////////////////////////////////////

#ifndef _PHYSICSENGINE_H_
#define _PHYSICSENGINE_H_

////////////////////////////////////////////////////////////////////////////////

#ifndef _COMMONTYPES_H_
#include "commontypes.h"
#endif

#ifndef _CONTACTLISTENER_H_
#include "contactlistener.h"
#endif

#include "box2d.h"
#include <boost/scoped_ptr.hpp>

////////////////////////////////////////////////////////////////////////////////

class SPlayer;
class SGameObject;
class SBullet;
struct MapOnServer;

////////////////////////////////////////////////////////////////////////////////

/** External Box2D physical engine
*
*  @author   Roman Pasechnik
*  @author   Anastasia Karpinska
*  @since    Jan 24th, 2010
*  @updated  Apr 17th, 2010
*/
class PhysicsEngine
{
////////////////////////////////////////////////////////////////////////////////

public:

////////////////////////////////////////////////////////////////////////////////


    /** Constructor */
    PhysicsEngine();


    /** Destructor */
    ~PhysicsEngine();


////////////////////////////////////////////////////////////////////////////////


    /** Creates bullet physical object */
    void CreatePlayer( SPlayer& _player );


    /** Creates bullet physical object */
    void CreateBullet( SBullet& _bullet, const Vector& _impulse );


    /** Creates physical object */
    void CreateObject( b2FixtureDef& _fixture, SGameObject& _object, bool _isStatic = false );


    /** Destroys physical object */
    void DestroyObject( SGameObject& _object );


    /** Sets pointer to SGameObject as user data for physics object */
    void SetUserData( SGameObject& _userData );


    /** Applies impulse on object */
    void ApplyImpulse( SGameObject& _object,
                       const Vector& _impulse );


    /** Set world map */
    void SetMap( const MapOnServer& _map );


////////////////////////////////////////////////////////////////////////////////


    /** Updates objects states */
    void Update( size_t _dt );


////////////////////////////////////////////////////////////////////////////////

private:

////////////////////////////////////////////////////////////////////////////////


    /** Bounding box for the world */
    b2AABB m_WorldAABB;


    /** The world object */
    boost::scoped_ptr<b2World> m_World;


    /** Contact listener */
    ContactListener m_ContactListener;

    
////////////////////////////////////////////////////////////////////////////////
};


////////////////////////////////////////////////////////////////////////////////

#endif

////////////////////////////////////////////////////////////////////////////////
